/*
 * Copyright 2005-2013 finalist.cn. All rights reserved.
 * Support: http://www.finalist.cn
 * License: http://www.finalist.cn/license
 */
package com.finalist.entity;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.PrePersist;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.Valid;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.finalist.Setting;
import com.finalist.util.DateUtil;
import com.finalist.util.SettingUtils;

/**
 * Entity - 订单
 * 
 * @author Finalist IT Group
 * @version 3.0
 */
@Entity
@Table(name = "xx_order")
@SequenceGenerator(name = "sequenceGenerator", sequenceName = "xx_order_sequence")
public class Order extends BaseEntity
{

    private static final long serialVersionUID = 8370942500343156156L;

    /** 订单名称分隔符 */
    private static final String NAME_SEPARATOR = " ";

    /**
     * 订单状态
     */
    public enum OrderStatus
    {

        /** 未确认 */
        unconfirmed,

        /** 已确认 */
        confirmed,

        /** 已完成 */
        completed,

        /** 已取消 */
        cancelled
    }

    public enum Gender
    {

        /** 男 */
        male,

        /**女 */
        female,
    }
    
    
    public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public Gender getGender() {
		return gender;
	}

	public void setGender(Gender gender) {
		this.gender = gender;
	}

	/**
     * 支付状态
     */
    public enum PaymentStatus
    {

        /** 未支付 */
        unpaid,

        /** 部分支付 */
        partialPayment,

        /** 已支付 */
        paid,

        /** 部分退款 */
        partialRefunds,

        /** 已退款 */
        refunded
    }

    /**
     * 配送状态
     */
    public enum ShippingStatus
    {

        /** 未发货 */
        unshipped,

        /** 部分发货 */
        partialShipment,

        /** 已发货 */
        shipped,

        /** 部分退货 */
        partialReturns,

        /** 已退货 */
        returned
    }

    /**
     * 验货状态
     */
    public enum InspectionStatus
    {
        /** 未验货*/
        init,
        /** 验货失败*/
        fail,
      //** 部分验货成功*//*
        partOfTheSuccess,
        /** 验货成功*/
        success
    }

    /**
     * 发票内容
     */
    public enum InvoiceContent
    {
        /** 不开发票 */
        no,
        /** 明细 */
        detail,
        /** 办公用品 */
        office,
        /** 电脑配件 */
        computer,
        /** 耗材 */
        consume
    }

    /**
     * 订单类别
     */
    public enum Category
    {

        /** 秒商城 */
        miaoShop,

        /** 微信商城 */
        weixinShop,

        /** app */
        appShop

    }

    /** 订单编号 */
    private String sn;
    
    /** 商户id */
    private Long adminId;

    public Long getAdminId() {
		return adminId;
	}

	public void setAdminId(Long adminId) {
		this.adminId = adminId;
	}

	/** 订单状态 */
    private OrderStatus orderStatus;

    /** 支付状态 */
    private PaymentStatus paymentStatus;

    /** 配送状态 */
    private ShippingStatus shippingStatus;

    /** 验货状态 */
    private InspectionStatus inspectionStatus = InspectionStatus.init;

    /** 订单类别 */
    private Category category;

    public Category getCategory()
    {
        return category;
    }

    public void setCategory(Category category)
    {
        this.category = category;
    }

    /** 支付手续费 */
    private BigDecimal fee;

    /** 运费 */
    private BigDecimal freight;

    /** 促销折扣 */
    private BigDecimal promotionDiscount;

    /** 优惠券折扣 */
    private BigDecimal couponDiscount;

    /** 调整金额 */
    private BigDecimal offsetAmount;

    /** 已付金额 */
    private BigDecimal amountPaid;

    /** 赠送积分 */
    private Long point;

    /** 收货人 */
    private String consignee;

    /** 地区名称 */
    private String areaName;

    /** 地址 */
    private String address;

    /** 邮编 */
    private String zipCode;

    /** 电话 */
    private String phone;
    
    /** 邮箱*/
    private String email;
    
    private Gender gender;
    
    private Date goDate;
    
    private Boolean isEffective = false; //订单是否有效
    
    /**
     * 该订单的购买者是否同行人可见
     */
    private Boolean isAssociateShow = false;
    
    private Long adultNum;
    private Long childrenNum;
    private Boolean isShareHouse;
    private String productName;
    
    public Boolean getIsAssociateShow() {
		return isAssociateShow;
	}

	public void setIsAssociateShow(Boolean isAssociateShow) {
		this.isAssociateShow = isAssociateShow;
	}
	
	@JsonProperty
	public String getProductName() {
		return productName;
	}

	public void setProductName(String productName) {
		this.productName = productName;
	}

	public Boolean getIsShareHouse() {
		return isShareHouse;
	}

	public void setIsShareHouse(Boolean isShareHouse) {
		this.isShareHouse = isShareHouse;
	}

	public Date getGoDate() {
		return goDate;
	}

	public void setGoDate(Date goDate) {
		this.goDate = goDate;
	}

	@JsonProperty
	public Long getAdultNum() {
		return adultNum;
	}

	public void setAdultNum(Long adultNum) {
		this.adultNum = adultNum;
	}
	
	@JsonProperty
	public Long getChildrenNum() {
		return childrenNum;
	}

	public void setChildrenNum(Long childrenNum) {
		this.childrenNum = childrenNum;
	}

	/** 是否开据发票 */
    private Boolean isInvoice;

    /** 是否开通来电显示 */
    private Boolean isOpenCallsDisplay;

    /** 发票抬头 */
    private String invoiceTitle;

    private InvoiceContent invoiceContent = InvoiceContent.no;

    /** 税金 */
    private BigDecimal tax;

    public Boolean getIsOpenCallsDisplay()
    {
        return isOpenCallsDisplay;
    }

    public void setIsOpenCallsDisplay(Boolean isOpenCallsDisplay)
    {
        this.isOpenCallsDisplay = isOpenCallsDisplay;
    }

    /** 附言 */
    private String memo;

    /** 促销 */
    private String promotion;

    /** 到期时间 */
    private Date expire;

    /** 锁定到期时间 */
    private Date lockExpire;

    /** 是否已分配库存 */
    private Boolean isAllocatedStock;

    /** 支付方式名称 */
    private String paymentMethodName;

    /** 配送方式名称 */
    private String shippingMethodName;

    /** 地区 */
    private Area area;

    /** 妙关爱 端使用者所在区域 地区 */
    private BossArea areaMiao;

    /**
     * 获取妙关爱 端使用者所在区域 地区
     * 
     * @return 妙关爱 端使用者所在区域 地区
     */
    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    public BossArea getAreaMiao()
    {
        return areaMiao;
    }

    public void setAreaMiao(BossArea areaMiao)
    {
        this.areaMiao = areaMiao;
    }

    /** 支付方式 */
    private PaymentMethod paymentMethod;


    /**云服务老用户手机号 */
    private String cloundServicesPhone;

    /**云服务激活码 */
    private String cloundSersActivationCode;

    public String getCloundServicesPhone()
    {
        return cloundServicesPhone;
    }

    public void setCloundServicesPhone(String cloundServicesPhone)
    {
        this.cloundServicesPhone = cloundServicesPhone;
    }

    public String getCloundSersActivationCode()
    {
        return cloundSersActivationCode;
    }

    public void setCloundSersActivationCode(String cloundSersActivationCode)
    {
        this.cloundSersActivationCode = cloundSersActivationCode;
    }


    /** 机主姓名 */
    private String phoneName;

    /** 身份证号 */
    private String idCard;
    
    /** 身份证地址 */
    private String idCardAddress;

    public String getIdCardAddress() {
		return idCardAddress;
	}

	public void setIdCardAddress(String idCardAddress) {
		this.idCardAddress = idCardAddress;
	}

	/**选中手机号 */
    private String selectedPhone;

    /**选中手机号乐语价 */
    private BigDecimal selectedPhonePrice;

    /**入网城市 */
    private String networkCity;

    /** 操作员 */
    private Admin operator;

    /** 会员 */
    private Member member;

    /** 优惠码 */
    private CouponCode couponCode;

    /** 优惠券 */
    private List<Coupon> coupons = new ArrayList<Coupon>();

    /** 订单项 */
    private List<OrderItem> orderItems = new ArrayList<OrderItem>();

    /** 订单日志 */
    private Set<OrderLog> orderLogs = new HashSet<OrderLog>();


    /** 收款单 */
    private Set<Payment> payments = new HashSet<Payment>();

    /** 退款单 */
    private Set<Refunds> refunds = new HashSet<Refunds>();


    /** 退货单 */
    private Set<Returns> returns = new HashSet<Returns>();

    /** 端使用者所在区域 */
    private BossArea boseArea;

    /**
     * 端使用者所在区域
     * 
     * @return 地区
     */
    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    public BossArea getBoseArea()
    {
        return boseArea;
    }

    public void setBoseArea(BossArea boseArea)
    {
        this.boseArea = boseArea;
    }

    /**
     * 获取订单编号
     * 
     * @return 订单编号
     */
    @Column(nullable = false, updatable = false, unique = true, length = 100)
    @JsonProperty
    public String getSn()
    {
        return sn;
    }

    /**
     * 设置订单编号
     * 
     * @param sn
     *            订单编号
     */
    public void setSn(String sn)
    {
        this.sn = sn;
    }

    /**
     * 获取订单状态
     * 
     * @return 订单状态
     */
    @Column(nullable = false)
    public OrderStatus getOrderStatus()
    {
        return orderStatus;
    }

    /**
     * 设置订单状态
     * 
     * @param orderStatus
     *            订单状态
     */
    public void setOrderStatus(OrderStatus orderStatus)
    {
        this.orderStatus = orderStatus;
    }

    /**
     * 获取支付状态
     * 
     * @return 支付状态
     */
    @Column(nullable = false)
    public PaymentStatus getPaymentStatus()
    {
        return paymentStatus;
    }

    /**
     * 设置支付状态
     * 
     * @param paymentStatus
     *            支付状态
     */
    public void setPaymentStatus(PaymentStatus paymentStatus)
    {
        this.paymentStatus = paymentStatus;
    }

    /**
     * 获取配送状态
     * 
     * @return 配送状态
     */
    @Column(nullable = true)
    public ShippingStatus getShippingStatus()
    {
        return shippingStatus;
    }

    /**
     * 设置配送状态
     * 
     * @param shippingStatus
     *            配送状态
     */
    public void setShippingStatus(ShippingStatus shippingStatus)
    {
        this.shippingStatus = shippingStatus;
    }

    /**
     * 获取验货状态
     * 
     * @return 验货状态
     */
    public InspectionStatus getInspectionStatus()
    {
        return inspectionStatus;
    }

    /**
     * 获取验货状态
     * 
     * @return 验货状态
     */
    public void setInspectionStatus(InspectionStatus inspectionStatus)
    {
        this.inspectionStatus = inspectionStatus;
    }

    /**
     * 获取支付手续费
     * 
     * @return 支付手续费
     */
    @Column(nullable = true, precision = 21, scale = 6)
    public BigDecimal getFee()
    {
        return fee;
    }

    /**
     * 设置支付手续费
     * 
     * @param fee
     *            支付手续费
     */
    public void setFee(BigDecimal fee)
    {
        this.fee = fee;
    }

    /**
     * 获取运费
     * 
     * @return 运费
     */
    @NotNull
    @Min(0)
    @Digits(integer = 12, fraction = 3)
    @Column(nullable = true, precision = 21, scale = 6)
    public BigDecimal getFreight()
    {
        return freight;
    }

    /**
     * 设置运费
     * 
     * @param freight
     *            运费
     */
    public void setFreight(BigDecimal freight)
    {
        this.freight = freight;
    }

    /**
     * 获取促销折扣
     * 
     * @return 促销折扣
     */
    @Column(nullable = true, updatable = false, precision = 21, scale = 6)
    public BigDecimal getPromotionDiscount()
    {
        return promotionDiscount;
    }

    /**
     * 设置促销折扣
     * 
     * @param promotionDiscount
     *            促销折扣
     */
    public void setPromotionDiscount(BigDecimal promotionDiscount)
    {
        this.promotionDiscount = promotionDiscount;
    }

    /**
     * 获取优惠券折扣
     * 
     * @return 优惠券折扣
     */
    @Column(nullable = true, updatable = false, precision = 21, scale = 6)
    public BigDecimal getCouponDiscount()
    {
        return couponDiscount;
    }

    /**
     * 设置优惠券折扣
     * 
     * @param couponDiscount
     *            优惠券折扣
     */
    public void setCouponDiscount(BigDecimal couponDiscount)
    {
        this.couponDiscount = couponDiscount;
    }

    /**
     * 获取调整金额
     * 
     * @return 调整金额
     */
    @NotNull
    @Digits(integer = 12, fraction = 3)
    @Column(nullable = true, precision = 21, scale = 6)
    public BigDecimal getOffsetAmount()
    {
        return offsetAmount;
    }

    /**
     * 设置调整金额
     * 
     * @param offsetAmount
     *            调整金额
     */
    public void setOffsetAmount(BigDecimal offsetAmount)
    {
        this.offsetAmount = offsetAmount;
    }

    /**
     * 获取已付金额
     * 
     * @return 已付金额
     */
    @Column(nullable = true, precision = 21, scale = 6)
    public BigDecimal getAmountPaid()
    {
        return amountPaid;
    }

    /**
     * 设置已付金额
     * 
     * @param amountPaid
     *            已付金额
     */
    public void setAmountPaid(BigDecimal amountPaid)
    {
        this.amountPaid = amountPaid;
    }

    /**
     * 获取赠送积分
     * 
     * @return 赠送积分
     */
    @NotNull
    @Min(0)
    @Column(nullable = true)
    public Long getPoint()
    {
        return point;
    }

    /**
     * 设置赠送积分
     * 
     * @param point
     *            赠送积分
     */
    public void setPoint(Long point)
    {
        this.point = point;
    }

    /**
     * 获取收货人
     * 
     * @return 收货人
     */
    @NotEmpty
    @Length(max = 200)
    @Column(nullable = true)
    public String getConsignee()
    {
        return consignee;
    }

    /**
     * 设置收货人
     * 
     * @param consignee
     *            收货人
     */
    public void setConsignee(String consignee)
    {
        this.consignee = consignee;
    }

    /**
     * 获取地区名称
     * 
     * @return 地区名称
     */
    @Column(nullable = true)
    public String getAreaName()
    {
        return areaName;
    }

    /**
     * 设置地区名称
     * 
     * @param areaName
     *            地区名称
     */
    public void setAreaName(String areaName)
    {
        this.areaName = areaName;
    }

    /**
     * 获取地址
     * 
     * @return 地址
     */
    @NotEmpty
    @Length(max = 200)
    @Column(nullable = true)
    public String getAddress()
    {
        return address;
    }

    /**
     * 设置地址
     * 
     * @param address
     *            地址
     */
    public void setAddress(String address)
    {
        this.address = address;
    }

    /**
     * 获取邮编
     * 
     * @return 邮编
     */
    @NotEmpty
    @Length(max = 200)
    @Column(nullable = true)
    public String getZipCode()
    {
        return zipCode;
    }

    /**
     * 设置邮编
     * 
     * @param zipCode
     *            邮编
     */
    public void setZipCode(String zipCode)
    {
        this.zipCode = zipCode;
    }

    /**
     * 获取电话
     * 
     * @return 电话
     */
    @NotEmpty
    @Length(max = 200)
    @Column(nullable = true)
    public String getPhone()
    {
        return phone;
    }

    /**
     * 设置电话
     * 
     * @param phone
     *            电话
     */
    public void setPhone(String phone)
    {
        this.phone = phone;
    }

    /**
     * 获取是否开据发票
     * 
     * @return 是否开据发票
     */
    @NotNull
    @Column(nullable = true)
    public Boolean getIsInvoice()
    {
        return isInvoice;
    }

    /**
     * 设置是否开据发票
     * 
     * @param isInvoice
     *            是否开据发票
     */
    public void setIsInvoice(Boolean isInvoice)
    {
        this.isInvoice = isInvoice;
    }

    /**
     * 获取发票抬头
     * 
     * @return 发票抬头
     */
    @Length(max = 200)
    public String getInvoiceTitle()
    {
        return invoiceTitle;
    }

    /**
     * 设置发票抬头
     * 
     * @param invoiceTitle
     *            发票抬头
     */
    public void setInvoiceTitle(String invoiceTitle)
    {
        this.invoiceTitle = invoiceTitle;
    }

    /**
     * 获取税金
     * 
     * @return 税金
     */
    @Min(0)
    @Digits(integer = 12, fraction = 3)
    @Column(nullable = true, precision = 21, scale = 6)
    public BigDecimal getTax()
    {
        return tax;
    }

    /**
     * 设置税金
     * 
     * @param tax
     *            税金
     */
    public void setTax(BigDecimal tax)
    {
        this.tax = tax;
    }

    /**
     * 获取附言
     * 
     * @return 附言
     */
    @Length(max = 200)
    @JsonProperty
    public String getMemo()
    {
        return memo;
    }

    /**
     * 设置附言
     * 
     * @param memo
     *            附言
     */
    public void setMemo(String memo)
    {
        this.memo = memo;
    }

    /**
     * 获取促销
     * 
     * @return 促销
     */
    @Column(updatable = false)
    public String getPromotion()
    {
        return promotion;
    }

    /**
     * 设置促销
     * 
     * @param promotion
     *            促销
     */
    public void setPromotion(String promotion)
    {
        this.promotion = promotion;
    }

    /**
     * 获取到期时间
     * 
     * @return 到期时间
     */
    public Date getExpire()
    {
        return expire;
    }

    /**
     * 设置到期时间
     * 
     * @param expire
     *            到期时间
     */
    public void setExpire(Date expire)
    {
        this.expire = expire;
    }

    /**
     * 获取锁定到期时间
     * 
     * @return 锁定到期时间
     */
    public Date getLockExpire()
    {
        return lockExpire;
    }

    /**
     * 设置锁定到期时间
     * 
     * @param lockExpire
     *            锁定到期时间
     */
    public void setLockExpire(Date lockExpire)
    {
        this.lockExpire = lockExpire;
    }

    /**
     * 获取是否已分配库存
     * 
     * @return 是否已分配库存
     */
    @Column(nullable = true)
    public Boolean getIsAllocatedStock()
    {
        return isAllocatedStock;
    }

    /**
     * 设置是否已分配库存
     * 
     * @param isAllocatedStock
     *            是否已分配库存
     */
    public void setIsAllocatedStock(Boolean isAllocatedStock)
    {
        this.isAllocatedStock = isAllocatedStock;
    }

    /**
     * 获取支付方式名称
     * 
     * @return 支付方式名称
     */
    @Column(nullable = true)
    public String getPaymentMethodName()
    {
        return paymentMethodName;
    }

    /**
     * 设置支付方式名称
     * 
     * @param paymentMethodName
     *            支付方式名称
     */
    public void setPaymentMethodName(String paymentMethodName)
    {
        this.paymentMethodName = paymentMethodName;
    }

    /**
     * 获取配送方式名称
     * 
     * @return 配送方式名称
     */
    @Column(nullable = true)
    public String getShippingMethodName()
    {
        return shippingMethodName;
    }

    /**
     * 设置配送方式名称
     * 
     * @param shippingMethodName
     *            配送方式名称
     */
    public void setShippingMethodName(String shippingMethodName)
    {
        this.shippingMethodName = shippingMethodName;
    }

    /**
     * 获取地区
     * 
     * @return 地区
     */
    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    public Area getArea()
    {
        return area;
    }

    /**
     * 设置地区
     * 
     * @param area
     *            地区
     */
    public void setArea(Area area)
    {
        this.area = area;
    }

    /**
     * 获取支付方式
     * 
     * @return 支付方式
     */
    @NotNull
    @ManyToOne(fetch = FetchType.LAZY)
    public PaymentMethod getPaymentMethod()
    {
        return paymentMethod;
    }

    /**
     * 设置支付方式
     * 
     * @param paymentMethod
     *            支付方式
     */
    public void setPaymentMethod(PaymentMethod paymentMethod)
    {
        this.paymentMethod = paymentMethod;
    }


    /**
     * 获取机主姓名
     * 
     * @return 机主姓名
     */
    @Length(max = 200)
    public String getPhoneName()
    {
        return phoneName;
    }

    /**
     * 设置机主姓名
     * 
     * @param phoneName
     *             机主姓名
     */
    public void setPhoneName(String phoneName)
    {
        this.phoneName = phoneName;
    }

    /**
     * 获取身份证号
     * 
     * @return 身份证号
     */
    @Length(max = 200)
    public String getIdCard()
    {
        return idCard;
    }

    /**
     * 设置身份证号
     * 
     * @param idCard
     *            身份证号
     */
    public void setIdCard(String idCard)
    {
        this.idCard = idCard;
    }

    /**
     * 获取选中号码
     * 
     * @return 选中号码
     */
    @Length(max = 200)
    public String getSelectedPhone()
    {
        return selectedPhone;
    }

    /**
     * 设置选中号码
     * 
     * @param selectedPhone
     *              选中号码
     */
    public void setSelectedPhone(String selectedPhone)
    {
        this.selectedPhone = selectedPhone;
    }

    /**
     * 获取选中号码价格
     * 
     * @return 选中号码价格
     */
    public BigDecimal getSelectedPhonePrice()
    {
        return selectedPhonePrice;
    }

    /**
     * 设置选中号码价格
     * 
     * @param selectedPhonePrice
     *                选中号码价格
     */
    public void setSelectedPhonePrice(BigDecimal selectedPhonePrice)
    {
        this.selectedPhonePrice = selectedPhonePrice;
    }

    /**
     * 获取入网城市
     * 
     * @return 入网城市
     */
    @Length(max = 200)
    public String getNetworkCity()
    {
        return networkCity;
    }

    /**
     * 设置入网城市
     * 
     * @param networkCity
     *              入网城市
     */
    public void setNetworkCity(String networkCity)
    {
        this.networkCity = networkCity;
    }


    /**
     * 获取操作员
     * 
     * @return 操作员
     */
    @ManyToOne(fetch = FetchType.LAZY)
    public Admin getOperator()
    {
        return operator;
    }

    /**
     * 设置操作员
     * 
     * @param operator
     *            操作员
     */
    public void setOperator(Admin operator)
    {
        this.operator = operator;
    }

    /**
     * 获取会员
     * 
     * @return 会员
     */
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(nullable = true, updatable = false)
    public Member getMember()
    {
        return member;
    }

    /**
     * 设置会员
     * 
     * @param member
     *            会员
     */
    public void setMember(Member member)
    {
        this.member = member;
    }

    /**
     * 获取优惠码
     * 
     * @return 优惠码
     */
    @OneToOne(fetch = FetchType.LAZY)
    public CouponCode getCouponCode()
    {
        return couponCode;
    }

    /**
     * 设置优惠码
     * 
     * @param couponCode
     *            优惠码
     */
    public void setCouponCode(CouponCode couponCode)
    {
        this.couponCode = couponCode;
    }

    /**
     * 获取优惠券
     * 
     * @return 优惠券
     */
    @ManyToMany(fetch = FetchType.LAZY)
    @JoinTable(name = "xx_order_coupon")
    public List<Coupon> getCoupons()
    {
        return coupons;
    }

    /**
     * 设置优惠券
     * 
     * @param coupons
     *            优惠券
     */
    public void setCoupons(List<Coupon> coupons)
    {
        this.coupons = coupons;
    }

    /**
     * 获取订单项
     * 
     * @return 订单项
     */
    @Valid
    @NotEmpty
    @OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @OrderBy("isGift asc")
    @JsonProperty
    public List<OrderItem> getOrderItems()
    {
        return orderItems;
    }

    /**
     * 设置订单项
     * 
     * @param orderItems
     *            订单项
     */
    public void setOrderItems(List<OrderItem> orderItems)
    {
        this.orderItems = orderItems;
    }

    /**
     * 获取订单日志
     * 
     * @return 订单日志
     */
    @OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @OrderBy("createDate asc")
    public Set<OrderLog> getOrderLogs()
    {
        return orderLogs;
    }

    /**
     * 设置订单日志
     * 
     * @param orderLogs
     *            订单日志
     */
    public void setOrderLogs(Set<OrderLog> orderLogs)
    {
        this.orderLogs = orderLogs;
    }


    /**
     * 获取收款单
     * 
     * @return 收款单
     */
    @OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @OrderBy("createDate asc")
    public Set<Payment> getPayments()
    {
        return payments;
    }

    /**
     * 设置收款单
     * 
     * @param payments
     *            收款单
     */
    public void setPayments(Set<Payment> payments)
    {
        this.payments = payments;
    }

    /**
     * 获取退款单
     * 
     * @return 退款单
     */
    @OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @OrderBy("createDate asc")
    public Set<Refunds> getRefunds()
    {
        return refunds;
    }

    /**
     * 设置退款单
     * 
     * @param refunds
     *            退款单
     */
    public void setRefunds(Set<Refunds> refunds)
    {
        this.refunds = refunds;
    }


    /**
     * 获取退货单
     * 
     * @return 退货单
     */
    @OneToMany(mappedBy = "order", fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
    @OrderBy("createDate asc")
    public Set<Returns> getReturns()
    {
        return returns;
    }

    /**
     * 设置退货单
     * 
     * @param returns
     *            退货单
     */
    public void setReturns(Set<Returns> returns)
    {
        this.returns = returns;
    }

    /**
     * 获取订单名称
     * 
     * @return 订单名称
     */
    @Transient
    public String getName()
    {
        StringBuffer name = new StringBuffer();
        if (getOrderItems() != null)
        {
            for (OrderItem orderItem : getOrderItems())
            {
                if (orderItem != null && orderItem.getFullName() != null)
                {
                    name.append(NAME_SEPARATOR).append(orderItem.getFullName());
                }
            }
            if (name.length() > 0)
            {
                name.deleteCharAt(0);
            }
        }
        return name.toString();
    }

    /**
     * 获取商品重量
     * 
     * @return 商品重量
     */
    @Transient
    public int getWeight()
    {
        int weight = 0;
        if (getOrderItems() != null)
        {
            for (OrderItem orderItem : getOrderItems())
            {
                if (orderItem != null)
                {
                    weight += orderItem.getTotalWeight();
                }
            }
        }
        return weight;
    }

    /**
     * 获取商品数量
     * 
     * @return 商品数量
     */
    @Transient
    public int getQuantity()
    {
        int quantity = 0;
        if (getOrderItems() != null)
        {
            for (OrderItem orderItem : getOrderItems())
            {
                if (orderItem != null && orderItem.getQuantity() != null)
                {
                    quantity += orderItem.getQuantity();
                }
            }
        }
        return quantity;
    }

    /**
     * 获取已发货数量
     * 
     * @return 已发货数量
     */
    @Transient
    public int getShippedQuantity()
    {
        int shippedQuantity = 0;
        if (getOrderItems() != null)
        {
            for (OrderItem orderItem : getOrderItems())
            {
                if (orderItem != null && orderItem.getShippedQuantity() != null)
                {
                    shippedQuantity += orderItem.getShippedQuantity();
                }
            }
        }
        return shippedQuantity;
    }

    /**
     * 获取已退货数量
     * 
     * @return 已退货数量
     */
    @Transient
    public int getReturnQuantity()
    {
        int returnQuantity = 0;
        if (getOrderItems() != null)
        {
            for (OrderItem orderItem : getOrderItems())
            {
                if (orderItem != null && orderItem.getReturnQuantity() != null)
                {
                    returnQuantity += orderItem.getReturnQuantity();
                }
            }
        }
        return returnQuantity;
    }

    /**
     * 获取商品价格
     * 
     * @return 商品价格
     */
    @Transient
    public BigDecimal getPrice()
    {
        BigDecimal price = new BigDecimal(0);
        if (getOrderItems() != null)
        {
            for (OrderItem orderItem : getOrderItems())
            {
                if (orderItem != null && this.getCategory() != null)
                {
                    if (orderItem.getWeiXinSubtotal() != null && this.getCategory().equals(Category.weixinShop))
                    {
                        price = price.add(orderItem.getWeiXinSubtotal());
                    }
                    else if (orderItem.getAppSubtotal() != null && this.getCategory().equals(Category.appShop))
                    {
                        price = price.add(orderItem.getAppSubtotal());
                    }
                    else if (orderItem.getSubtotal() != null)
                    {
                        price = price.add(orderItem.getSubtotal());
                    }
                }
            }
        }
        return price;
    }

    /**
     * 获取订单金额
     * 
     * @return 订单金额
     */
    @Transient
    public BigDecimal getAmount()
    {
    	BigDecimal amount = new BigDecimal(0);
    	if(orderItems!=null&&orderItems.size()!=0){
	    	Product product=orderItems.get(0).getProduct();
	    	if(product!=null){
	    		BigDecimal adultAmount=new BigDecimal(0);
	    		BigDecimal childrenAmount=new BigDecimal(0);
	    		if(isShareHouse!=null&&isShareHouse){
	    			if(product.getChildrenPrice()!=null){
	    				childrenAmount=product.getChildrenPrice().multiply(new BigDecimal(childrenNum));
	    			}
	    			adultAmount=product.getPrice().multiply(new BigDecimal(adultNum));
	    		}else{
	    			if(product.getChildrenPrice()!=null){
	    				childrenAmount=(product.getChildrenPrice().add(product.getHoursePrice())).multiply(new BigDecimal(childrenNum));
	    			}
	    			adultAmount=(product.getPrice().add(product.getHoursePrice())).multiply(new BigDecimal(adultNum));
	    		}
	    		amount=adultAmount.add(childrenAmount);
	    	}
    	}
        return amount;
    }

    /**
     * 获取应付金额
     * 
     * @return 应付金额
     */
    @Transient
    public BigDecimal getAmountPayable()
    {
        BigDecimal amountPayable = getAmount().subtract(getAmountPaid());
        return amountPayable.compareTo(new BigDecimal(0)) > 0 ? amountPayable : new BigDecimal(0);
    }

    /**
     * 是否已过期
     * 
     * @return 是否已过期
     */
    @Transient
    public boolean isExpired()
    {
        return getExpire() != null && new Date().after(getExpire());
    }

    /**
     * 获取订单项
     * 
     * @param sn
     *            商品编号
     * @return 订单项
     */
    @Transient
    public OrderItem getOrderItem(String sn)
    {
        if (sn != null && getOrderItems() != null)
        {
            for (OrderItem orderItem : getOrderItems())
            {
                if (orderItem != null && sn.equalsIgnoreCase(orderItem.getSn()))
                {
                    return orderItem;
                }
            }
        }
        return null;
    }

    /**
     * 判断是否已锁定
     * 
     * @param operator
     *            操作员
     * @return 是否已锁定
     */
    @Transient
    public boolean isLocked(Admin operator)
    {
        return getLockExpire() != null && new Date().before(getLockExpire()) && ((operator != null && !operator.equals(getOperator())) || (operator == null && getOperator() != null));
    }

    /**
     * 计算税金
     * 
     * @return 税金
     */
    @Transient
    public BigDecimal calculateTax()
    {
        BigDecimal tax = new BigDecimal(0);
        Setting setting = SettingUtils.get();
        if (setting.getIsTaxPriceEnabled())
        {
            BigDecimal amount = getPrice();
            if (getPromotionDiscount() != null)
            {
                amount = amount.subtract(getPromotionDiscount());
            }
            if (getCouponDiscount() != null)
            {
                amount = amount.subtract(getCouponDiscount());
            }
            if (getOffsetAmount() != null)
            {
                amount = amount.add(getOffsetAmount());
            }
            tax = amount.multiply(new BigDecimal(setting.getTaxRate().toString()));
        }
        return setting.setScale(tax);
    }

    /**
     * 持久化前处理
     */
    @PrePersist
    public void prePersist()
    {
        if (getArea() != null)
        {
            setAreaName(getArea().getFullName());
        }
        if (getPaymentMethod() != null)
        {
            setPaymentMethodName(getPaymentMethod().getName());
        }
    }

    /**
     * 更新前处理
     */
    @PreUpdate
    public void preUpdate()
    {
        if (getArea() != null)
        {
            setAreaName(getArea().getFullName());
        }
        if (getPaymentMethod() != null)
        {
            setPaymentMethodName(getPaymentMethod().getName());
        }
    }

    public InvoiceContent getInvoiceContent()
    {
        return invoiceContent;
    }

    public void setInvoiceContent(InvoiceContent invoiceContent)
    {
        this.invoiceContent = invoiceContent;
    }
    
    
    @Transient
    public String getGoDateString()
    {
        if(goDate!=null){
        	return DateUtil.formatDate(goDate);
        }
        return null;
    }
    
    @Transient
    public Long getTotalNum(){
    	if(adultNum!=null&&childrenNum!=null){
    		return adultNum+childrenNum;
    	}
    	return 0l;
    }

    
    @Transient
    public Long getTmepAdult(){
    	Long tempAdult=0L;
    	if(orderItems!=null&&orderItems.size()!=0){
    		for(OrderItem orderItem:orderItems){
    			if(orderItem!=null&&orderItem.getIsAdult()){
    				tempAdult++;
    			}
    		}
    	}
    	return tempAdult;
    }
    
    @Transient
    public Long getTmepChildren(){
    	Long tempChildren=0L;
    	if(orderItems!=null&&orderItems.size()!=0){
    		for(OrderItem orderItem:orderItems){
    			if(orderItem!=null&&!orderItem.getIsAdult()){
    				tempChildren++;
    			}
    		}
    	}
    	return tempChildren;
    }
    
	public Boolean getIsEffective() {
		return isEffective;
	}

	public void setIsEffective(Boolean isEffective) {
		this.isEffective = isEffective;
	}
    
    
    
}